package com.landmark;

import java.awt.EventQueue;
import java.io.FileWriter;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.htmlparser.Parser;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class BarcoCat extends SwingWorker<Boolean, Boolean> {

    FileWriter fw = null;
    FileWriter errorFile = null;
    int pageNo;
    StringBuffer sb = new StringBuffer();
    Hashtable<String, String> htModelLinks = new Hashtable<String, String>();
    String status = "";
    JTextArea txtArea;
    UMProgressBar pBar = null;
    int lineCount = 0;

    @Override
    protected Boolean doInBackground() throws Exception {
        start();
        return true;
    }

    @Override
    protected void done() {
        Util.taskCompleteMsg(status);
    }

    public void start() {
        try {
            String dirName = "./outputs";
            String imagesPath = "./outputs/BarcoImages";
            String barcoSwatchesPath = "./outputs/BarcoSwatches";

            Util.createDirectory(dirName);
            Util.createDirectory(imagesPath);
            Util.createDirectory(barcoSwatchesPath);

            txtArea = Util.createOutputFile("Barco");
            HelperBean helperBean = Util.getHelperBean();

            fw = new FileWriter(helperBean.getOutputFile());
            errorFile = new FileWriter(helperBean.getErrorFile());

            // Here we get all the search pages from page 0 to 9 which we know by seeing the site
            for (pageNo = 1; pageNo <= 9; pageNo++) {
                if (Util.getHelperBean().isTerminateCurrentProcess()) {
                    break;
                }
                String str = "http://medical.barcouniforms.com/medical/catalog.asp?page=" + pageNo;
                txtArea.setText(str);
                txtArea.paintImmediately(txtArea.getVisibleRect());
                processCategoryPage(str);
            }

            txtArea.append("\nFiles are located at : \n" + helperBean.getOutputFile().getAbsolutePath() + "\n" + helperBean.getErrorFile().getAbsolutePath() + "\n");
            txtArea.append("Total products : " + htModelLinks.size() + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            Util.getHelperBean().setLineCount(htModelLinks.size());

            iterateCollection(htModelLinks);

            if (fw != null) {
                fw.close();
            }

        } catch (Exception e) {
            status = e.toString();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        status = status.trim().equals("") ? "Done processing." : status;
        if (Util.getHelperBean().isTerminateCurrentProcess()) {
            status = "Process Terminated";
        }
        txtArea.append("\n" + status);
    }

    /**
     *
     * @param htLinks
     */
    private void iterateCollection(Hashtable<String, String> htLinks) throws Exception {
        lineCount = 0;
        pBar = new UMProgressBar();
        Enumeration<String> keys = htLinks.keys();
        fw.write("Product_Id, Product_Name, Product_Image_URL\n");
        while (keys.hasMoreElements()) {
            if (Util.getHelperBean().isTerminateCurrentProcess()) {
                break;
            }
            String key = (String) keys.nextElement();
            txtArea.append("Processing page: " + key + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            sb = new StringBuffer();
            Util.getHelperBean().setCurrentCount(lineCount++);

            processModels(htLinks.get(key).toString());
            fw.write(sb.toString().replaceAll("\n", "").replace("   ", "").replaceAll("<#NEWLINE#>", "\n"));
            fw.write("\n");
            fw.flush();
            if (Util.getHelperBean().getLineCount() == lineCount) {
                Util.getHelperBean().setProcessingDone(true);
                pBar.close();
            }
            EventQueue.invokeLater(pBar);
        }
    }

    /**
     *
     * @param aUrl
     */
    private void processModels(String aUrl)  {
        try {
            Parser parser = Util.getParserFromUrl(aUrl, null);

            NodeList nl = parser.parse(null);
            String prdtIdLs = Util.getHelperBean().getInputHTML().select(".part").text();

            String prdtNameLs = Util.getHelperBean().getInputHTML().select(".details").text();

            System.out.println(prdtIdLs + " , " + prdtNameLs);
            Elements prdtImages = Util.getHelperBean().getInputHTML().select(".itemimg").select("img[src$=.jpg]");
            Elements prdtSwatches = Util.getHelperBean().getInputHTML().select(".colors").select("img[src$=.jpg]");
            // gets all the main images
            for (Element ele : prdtImages) {
                //System.out.println(ele.absUrl("src"));
                sb.append(prdtIdLs);
                sb.append(",");
                sb.append(prdtNameLs);
                sb.append(",");
                sb.append(ele.absUrl("src"));
                sb.append("<#NEWLINE#>");
                try {
                    Util.saveImage(ele.absUrl("src"), "./outputs/BarcoImages", null);
                } catch (Exception e) {
                    System.out.print(e.getMessage());
                    continue;
                }
            }
            // gets all the swatches
            for (Element ele : prdtSwatches) {
                String src = URLEncoder.encode(ele.absUrl("src"));

                src = URLDecoder.decode(src.replaceAll("5C", "2F"));
                Util.saveImage(src, "./outputs/BarcoSwatches", null);
            }
        } catch (SocketTimeoutException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        } catch(Exception e ) {
            
        }
    }

    private void processCategoryPage(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select("div#catalog").select("a[href]");
            System.out.println(elements.size());
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                htModelLinks.put(absoluteUrl, absoluteUrl);
            }
        } catch (SocketTimeoutException e) {
            try {
                processCategoryPage(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                processCategoryPage(aUrl);
            } catch (Exception e1) {
            }
        }
    }
}
